package com.yan.service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

/**
 * @author dd
 * @date 2015-12-30 上午10:06:02
 */ 
//@Component
public class BaseRedisClient {

	@Autowired
	private JedisPool jedisPool;

	public Jedis getJedisInstance() {
		return jedisPool.getResource();
	}

	public void releaseResource(Jedis jedis) {
		if (jedis != null)
			jedis.close();
	}

	/**
	 * 判断key是否存在 @Title: exist @Description: TODO(这里用一句话描述这个方法的作用) @param @param
	 * key @param @return @param @throws Exception 参数 @return Boolean
	 * 返回类型 @throws
	 */
	public Boolean exist(String key) throws Exception {
		Jedis jedis = null;
		Boolean value = null;
		try {
			jedis = getJedisInstance();
			value = jedis.exists(key);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return value;
	}

	/**
	 * <p>
	 * 通过key获取储存在redis中的value
	 * </p>
	 * <p>
	 * 并释放连接
	 * </p>
	 * 
	 * @param key
	 * @return 成功返回value 失败返回null
	 */
	public String get(String key) throws Exception {
		Jedis jedis = null;
		String value = null;
		try {
			jedis = getJedisInstance();
			value = jedis.get(key);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return value;
	}

	/**
	 * <p>
	 * 向redis存入key和value,并释放连接资源
	 * </p>
	 * <p>
	 * 如果key已经存在 则覆盖
	 * </p>
	 * 
	 * @param key
	 * @param value
	 * @return 成功 返回OK 失败返回 0
	 */
	public String set(String key, String value) throws Exception {
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			return jedis.set(key, value);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
	}

	/**
	 * <p>
	 * 通过key向list尾部添加字符串
	 * </p>
	 * 
	 * @param key
	 * @param vals
	 *            可以是一个string 也可以使string数组
	 * @return 返回list的value个数
	 */
	public Long rpush(String key, String... vals) throws Exception {
		Jedis j = null;
		Long res = null;
		try {
			j = getJedisInstance();
			res = j.rpush(key, vals);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(j);
		}
		return res;
	}

	public String lIndex(String key, long index) throws Exception {
		Jedis j = null;
		String res = null;
		try {
			j = getJedisInstance();
			res = j.lindex(key, index);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(j);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key从list尾部删除一个value,并返回该元素
	 * </p>
	 * 
	 * @param key
	 * @return
	 */
	public String rpop(String key) throws Exception {
		Jedis jedis = null;
		String res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.rpop(key);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 向set中添加值
	 * </p>
	 * 
	 * @param key
	 * @return
	 */
	public Long sadd(String key, String... members) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.sadd(key, members);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 
	 * @param key
	 * @return
	 */
	public Pipeline pip() throws Exception {
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			Pipeline pip = jedis.pipelined();
			return pip;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			releaseResource(jedis);
		}
		return null;
	}

	/**
	 * <p>
	 * 通过key向zset中添加value,score,其中score就是用来排序的
	 * </p>
	 * <p>
	 * 如果该value已经存在则根据score更新元素
	 * </p>
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return
	 */
	public Long zadd(String key, Map<String, Double> scoreMembers) throws Exception {
		Jedis j = null;
		Long res = null;
		try {
			j = getJedisInstance();
			res = j.zadd(key, scoreMembers);
		} catch (Exception e) {
			// releaseBrokenResource(j);//释放redis对象
			throw e;
		} finally {
			releaseResource(j);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key向zset中添加value,score,其中score就是用来排序的
	 * </p>
	 * <p>
	 * 如果该value已经存在则根据score更新元素
	 * </p>
	 * 
	 * @param key
	 * @param score
	 * @param member
	 * @return
	 */
	public Long zadd(String key, double score, String member) throws Exception {
		Jedis j = null;
		Long res = null;
		try {
			j = getJedisInstance();
			res = j.zadd(key, score, member);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(j);// 返还到连接池
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key返回指定score内zset中的value
	 * </p>
	 * 
	 * @param key
	 * @param max
	 * @param min
	 * @return
	 */
	public Set<String> zrangeByScore(String key, double max, double min) throws Exception {
		Jedis jedis = null;
		Set<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zrangeByScore(key, max, min);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	// public Long zcount(String key){
	// Jedis j = null;
	// Long res = null;
	// try{
	// j = getJedisInstance();
	// res = j.zcard(key);
	// }catch(Exception e){
	// releaseBrokenResource(j);//释放redis对象
	// throw e;
	// }finally{
	// releaseResource(j);//返还到连接池
	// }
	// return res;
	// }

	/**
	 * 获取start 到end间的数据
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public Set<String> zrange(String key, long start, long end) throws Exception {
		Jedis jedis = null;
		Set<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zrange(key, start, end);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 获取sortedset条数
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public Long zcard(String key) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zcard(key);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 获取start 到end间的数据, 倒序
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public Set<String> zrevrange(String key, long start, long end) throws Exception {
		Jedis jedis = null;
		Set<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zrevrange(key, start, end);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 获取start 到end间的数据, 倒序
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public Set<String> zrevrangeByScore(String key, double max, double min) throws Exception {
		Jedis jedis = null;
		Set<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zrevrangeByScore(key, max, min);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key删除在zset中指定的value
	 * </p>
	 * 
	 * @param key
	 * @param members
	 *            可以使一个string 也可以是一个string数组
	 * @return
	 */
	public Long zrem(String key, String... members) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zrem(key, members);
		} catch (Exception e) {

			e.printStackTrace();
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key 对value进行加值-1操作,当value不是int类型时会返回错误,当key不存在是则value为1
	 * </p>
	 * 
	 * @param key
	 * @return 加值后的结果
	 */
	public Long decr(String key) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.decr(key);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key 对value进行加值+1操作,当value不是int类型时会返回错误,当key不存在是则value为1
	 * </p>
	 * 
	 * @param key
	 * @return 加值后的结果
	 */
	public Long incr(String key) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.incr(key);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key给field设置指定的值,如果key不存在则先创建,如果field已经存在,返回0
	 * </p>
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public Long hsetnx(String key, String field, String value) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hsetnx(key, field, value);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key同时设置 hash的多个field
	 * </p>
	 * 
	 * @param key
	 * @param hash
	 * @return 返回OK 异常返回null
	 */
	public String hmset(String key, Map<String, String> hash) throws Exception {
		Jedis jedis = null;
		String res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hmset(key, hash);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key同时设置 hash的多个field
	 * </p>
	 * 
	 * @param key
	 * @param hash
	 * @return 返回OK 异常返回null
	 */
	public Long hset(String key, String field, String value) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hset(key, field, value);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key 和 field 获取指定的 value
	 * </p>
	 * 
	 * @param key
	 * @param field
	 * @return 没有返回null
	 */
	public String hget(String key, String field) throws Exception {
		Jedis jedis = null;
		String res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hget(key, field);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key 和 fields 获取指定的value 如果没有对应的value则返回null
	 * </p>
	 * 
	 * @param key
	 * @param fields
	 *            可以使 一个String 也可以是 String数组
	 * @return
	 */
	public List<String> hmget(String key, String... fields) throws Exception {
		Jedis jedis = null;
		List<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hmget(key, fields);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	public Long hdel(String key, String field) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hdel(key, field);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key获取hash里所有值
	 * </p>
	 * 
	 * @param key
	 * @return 没有返回null
	 */
	public Map<String, String> hgetAll(String key) throws Exception {
		Jedis jedis = null;
		Map<String, String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hgetAll(key);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 
	 * @description 给指定key对应的hash表中指定字段的值加一定值
	 * @author lsl
	 * @createDate 2016年5月20日 上午9:54:49
	 * @version v1.0
	 * @param
	 * @return Long
	 */
	public Long hincrby(String key, String field, long value) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.hincrBy(key, field, value);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 设置对应key的过期时间
	 * 
	 * @param key
	 * @param seconds
	 *            秒
	 * @return 1：过期时间设置成功 0：表示对已设置的过期时间进行更新或者key不存在
	 * @since jedis2.1.3
	 */
	public Long expire(String key, int seconds) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.expire(key, seconds);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 删除对应的key @param keys @return 返回删除的个数 @throws
	 */
	public Long del(String... keys) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.del(keys);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key判断value是否是set中的元素
	 * </p>
	 * 
	 * @param key
	 * @param member
	 * @return
	 */
	public Boolean sismember(String key, String member) throws Exception {
		Jedis jedis = null;
		Boolean res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.sismember(key, member);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 获取start 到end间的数据
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public List<String> lrange(String key, long start, long end) throws Exception {
		Jedis jedis = null;
		List<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.lrange(key, start, end);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 通过key向list头部添加字符串
	 * </p>
	 * 
	 * @param key
	 * @param vals
	 *            可以是一个string 也可以使string数组
	 * @return 返回list的value个数
	 */
	public Long lpush(String key, String... values) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.lpush(key, values);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * <p>
	 * 取出set中的值
	 * </p>
	 * 
	 * @param key
	 * @return
	 */
	public Set<String> smembers(String key) throws Exception {
		Jedis jedis = null;
		Set<String> res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.smembers(key);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 删除set中的一个或多个值 @Title: srem @Description:
	 * TODO(这里用一句话描述这个方法的作用) @param @param key @param @param
	 * members @param @return @param @throws Exception 参数 @return
	 * Long 返回类型 @throws
	 */
	public Long srem(String key, String... members) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.srem(key, members);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	public Double zscore(String key, String member) throws Exception {
		Jedis jedis = null;
		Double res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.zscore(key, member);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}

	/**
	 * 
	 * @description 获取对应key的过期时间
	 * @author lsl
	 * @createDate 2016年5月20日 下午10:01:26
	 * @version v1.0
	 * @param
	 * @return Long
	 * @since 2.8 key存在没设置失效时间返回-1 key不存在返回-2
	 */
	public Long ttl(String key) throws Exception {
		Jedis jedis = null;
		Long res = null;
		try {
			jedis = getJedisInstance();
			res = jedis.ttl(key);
		} catch (Exception e) {

			throw e;
		} finally {
			releaseResource(jedis);
		}
		return res;
	}
	
	public byte[] getByte(String key) throws Exception {
		Jedis jedis = null;
		byte[] value = null;
		try {
			jedis = getJedisInstance();
			value = jedis.get(key.getBytes());
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
		return value;
	}
	
	public String setByte(byte[] key, byte[] value) throws Exception{
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			return jedis.set(key, value);
		} catch (Exception e) {
			throw e;
		} finally {
			releaseResource(jedis);
		}
	}
	
}
